package com.wh.data.model.exe;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import com.wh.data.pp.bp.SumBpCheckerWSumBpLb;
import com.wh.data.pp.bp.SumBpCheckerWSumFp;
import com.wh.data.pp.bp.SumBpTotalTimeProcessor;

/**
 * @author HuYao
 * 
 */
public class MultiCoreProcessor {

    static final int MAX_THREAD = 20;
    static final String rootDicPath = "z:\\updated random cases - fixed patients only"; //$NON-NLS-1$

    /**
     * @param args
     * @throws FileNotFoundException
     * @throws InterruptedException
     */
    public static void main(String[] args) throws FileNotFoundException,
	    InterruptedException {
	MultiCoreProcessor processor = new MultiCoreProcessor();
	processor.run();
    }

    /**
     * @throws FileNotFoundException
     * @throws InterruptedException
     */
    public void run() throws FileNotFoundException, InterruptedException {
	// TODO Auto-generated method stub
	FilePathProcessor fpp = new FilePathProcessor(rootDicPath);
	List<String> fstLvFds = fpp.getFirstLevelDir();
	final ThreadPool threads = new ThreadPool();
	for (String fstLvFd : fstLvFds) {
	    List<String> sndLvFds = fpp.get2ndLevelDir(fstLvFd);
	    for (String sndLvFd : sndLvFds) {
		List<String> trdLvFds = fpp.get3rdLevelDir(sndLvFd);
		for (final String trdLvFd : trdLvFds) {
		    for (int i = 1; i <= 5; i++) {
			VspThread t = new VspThread(threads, trdLvFd);
			threads.putToMap(t);
			t.start();
		    }
		}

	    }
	}

	for (Runnable run : threads.getMap().values()) {
	    ((Thread) run).join();
	}
    }

    class ThreadPool {
	final ConcurrentHashMap<String, Runnable> map = new ConcurrentHashMap<String, Runnable>();

	public synchronized void putToMap(Runnable thread) {
	    while (this.map.size() >= MAX_THREAD) {
		try {
		    wait();
		} catch (InterruptedException e) {
		    // TODO Auto-generated catch block
		    e.printStackTrace();
		}
	    }
	    this.map.put(String.valueOf(thread.hashCode()), thread);
	    notifyAll();
	}

	public synchronized void removeFromMap(Runnable thread) {
	    if (this.map.containsKey(String.valueOf(thread.hashCode()))) {
		this.map.remove(String.valueOf(thread.hashCode()));
		notifyAll();
	    }
	}

	public synchronized int size() {
	    return this.map.size();
	}

	public synchronized ConcurrentHashMap<String, Runnable> getMap() {
	    return this.map;
	}
    }

    class VspThread extends Thread {
	private volatile ThreadPool _pool;
	private volatile String _trdLvFd;

	public VspThread(ThreadPool pool, String trdLvFd) {
	    this._pool = pool;
	    this._trdLvFd = trdLvFd;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Thread#run()
	 */
	@Override
	public void run() {

	    try {
		String sum_bp_path = this._trdLvFd + File.separator + "sum_bp"; //$NON-NLS-1$
		String sum_fp_path = this._trdLvFd + File.separator + "sum_fp"; //$NON-NLS-1$
		String sum_bplb_path = this._trdLvFd + File.separator
			+ "sum_bp_lb"; //$NON-NLS-1$
		SumBpTotalTimeProcessor tp = new SumBpTotalTimeProcessor(
			sum_bp_path);
		SumBpCheckerWSumFp fpChecker = new SumBpCheckerWSumFp(
			sum_bp_path, sum_fp_path);
		SumBpCheckerWSumBpLb bplbChecker = new SumBpCheckerWSumBpLb(
			sum_bp_path, sum_bplb_path);
		try {
		    tp.process();
		    fpChecker.process();
		    bplbChecker.process();
		} catch (Exception e) {
		    e.printStackTrace();
		}
		tp = null;
		fpChecker = null;
		bplbChecker = null;
		System.out.println(this._trdLvFd);
		this._pool.removeFromMap(this);
	    } catch (Exception e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	    }

	}

    }
}
